package cn.edu.xust.api.controller;


import cn.edu.xust.Ro.MenuRo;
import cn.edu.xust.Ro.MenuTreeRo;
import cn.edu.xust.configuration.exception.Default200Exception;
import cn.edu.xust.configuration.exception.ErrorConstant;
import cn.edu.xust.entity.SysMenuEntity;
import cn.edu.xust.entity.SysMenuprivilegeEntity;
import cn.edu.xust.entity.SysRoleprivilegeEntity;
import cn.edu.xust.service.*;
import cn.edu.xust.util.R;
import cn.edu.xust.util.RedisUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author ufo
 * @email 2575829997@qq.com
 * @date 2022-09-06 17:32:09
 */
@RestController
@Slf4j

@RequestMapping("/api/sysroleprivilege")
public class ApiSysRoleprivilegeController {
    @Autowired
    private SysRoleprivilegeService sysRoleprivilegeService;
    @Autowired
    private SysRoleprivilegeService roleprivilegeService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SysMenuprivilegeService sysMenuprivilegeService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysUserroleService sysUserroleService;

    /**
     * 迁移旧数据
     */
//    @GetMapping("/transfer")
//    @Transactional(rollbackFor = Exception.class)
//    public R list() {
//        //现有的角色
//        List<SysRoleEntity> list = sysRoleService.list();
//
//        //现有角色id
//        List<Integer> collect = list.stream().map(SysRoleEntity::getRoleid).collect(Collectors.toList());
//
//        //所有映射
//        List<PrivilegeEntity> oldps = privilegeService.list();
//        HashMap<Integer, String> oldpmap = new HashMap<>();
//        for (PrivilegeEntity oldp : oldps) {
//            oldpmap.put(oldp.getPrivilegeId(), oldp.getMenuId());
//        }
//
//
//        //查询范围内的角色id的旧权限
//        List<RoleprivilegeEntity> roleprivilegeEntities = roleprivilegeService.getByRoleIds(collect);
//
//        for (RoleprivilegeEntity old : roleprivilegeEntities) {
//
//            Integer roleid = old.getRoleid();
//            Integer privilegeid = old.getPrivilegeid();
//            String menuid = oldpmap.get(privilegeid);
//
//
//            Integer cAdd = old.getCAdd();
//            Integer cDelete = old.getCDelete();
//            Integer cSelect = old.getCSelect();
//            Integer cUpdate = old.getCUpdate();
//
//            if (cAdd == 1) {
//                SysMenuprivilegeEntity sysMenuprivilege = sysMenuprivilegeService.getBymp(menuid, "add");
//                SysRoleprivilegeEntity sysRoleprivilegeEntity = new SysRoleprivilegeEntity();
//                sysRoleprivilegeEntity.setRoleid(roleid);
//                sysRoleprivilegeEntity.setPrivelegeid(sysMenuprivilege.getPrivilegeid());
//                sysRoleprivilegeService.save(sysRoleprivilegeEntity);
//            }
//            if (cDelete == 1) {
//                SysMenuprivilegeEntity sysMenuprivilege = sysMenuprivilegeService.getBymp(menuid, "del");
//                SysRoleprivilegeEntity sysRoleprivilegeEntity = new SysRoleprivilegeEntity();
//                sysRoleprivilegeEntity.setRoleid(roleid);
//                sysRoleprivilegeEntity.setPrivelegeid(sysMenuprivilege.getPrivilegeid());
//                sysRoleprivilegeService.save(sysRoleprivilegeEntity);
//            }
//            if (cSelect == 1) {
//                SysMenuprivilegeEntity sysMenuprivilege = sysMenuprivilegeService.getBymp(menuid, "select");
//                SysRoleprivilegeEntity sysRoleprivilegeEntity = new SysRoleprivilegeEntity();
//                sysRoleprivilegeEntity.setRoleid(roleid);
//                sysRoleprivilegeEntity.setPrivelegeid(sysMenuprivilege.getPrivilegeid());
//                sysRoleprivilegeService.save(sysRoleprivilegeEntity);
//            }
//            if (cUpdate == 1) {
//                SysMenuprivilegeEntity sysMenuprivilege = sysMenuprivilegeService.getBymp(menuid, "update");
//                SysRoleprivilegeEntity sysRoleprivilegeEntity = new SysRoleprivilegeEntity();
//                sysRoleprivilegeEntity.setRoleid(roleid);
//                sysRoleprivilegeEntity.setPrivelegeid(sysMenuprivilege.getPrivilegeid());
//                sysRoleprivilegeService.save(sysRoleprivilegeEntity);
//            }
//        }
//        return R.ok();
//    }

    /**
     * 获取某个用户的路由菜单 (for vue 路由 不含权限)
     */
    @PostMapping("/getroute")
    @Transactional(rollbackFor = Exception.class)
    public R getroute(@RequestBody JSONObject jsonObject) throws Default200Exception {
        String username = jsonObject.getString("username");
        String pwd = jsonObject.getString("pwd");
        MenuRo menuRo = sysMenuService.getrouteByNP(username, pwd);
        return R.ok().put("data", menuRo);
    }


    /**
     * 获取某个用户的管理权限菜单 (for antd tree 含权限)
     * 在子账户开新号时会用到，因为他可能会新建角色
     */
    @PostMapping("/getmenu")
    @Transactional(rollbackFor = Exception.class)
    public R getmenu(@RequestBody JSONObject jsonObject) throws Default200Exception {
        String username = jsonObject.getString("username");
        String pwd = jsonObject.getString("pwd");
        ArrayList<MenuTreeRo> menuTreeRos = sysMenuService.getTreeMenu(username, pwd);
        return R.ok().put("data", menuTreeRos);
    }

    /**
     * 获取某个角色的权限
     * 直接获取privelegeid就行了 注意 此处只获取二级目录下的权限点 一级目录别来
     */
    @PostMapping("/getprev")
    @Transactional(rollbackFor = Exception.class)
    public R getprev(@RequestBody JSONObject jsonObject) {
        String roleid = jsonObject.getString("roleid");


        List<SysMenuEntity> list = sysMenuService.list();
        List<Integer> menu2ids = list.stream().filter(e -> e.getMenurank().equals(2)).map(SysMenuEntity::getMenuid).collect(Collectors.toList());
        List<SysMenuprivilegeEntity> sysMenuprivilegeEntities = sysMenuprivilegeService.getbymenuids(menu2ids);
        List<Integer> canpids = sysMenuprivilegeEntities.stream().map(SysMenuprivilegeEntity::getPrivilegeid).collect(Collectors.toList());
        List<SysRoleprivilegeEntity> byroles = sysRoleprivilegeService.getByroles(roleid);
        List<SysRoleprivilegeEntity> collect1 = byroles.stream().filter(e -> canpids.contains(e.getPrivelegeid())).collect(Collectors.toList());
        List<Integer> collect = collect1.stream().map(SysRoleprivilegeEntity::getPrivelegeid).collect(Collectors.toList());
        List<String> data = new ArrayList<>();
        for (Integer integer : collect) {
            data.add(integer + "");
        }
        return R.ok().put("data", data);

    }

    /**
     * 修改某个角色的权限
     * 传入变化前和变化后的两个列表  注意:前端层级时，只会将子级下全勾选的结点id传过来，半勾选不会传！
     */
    @PostMapping("/updateroleprev")
    @Transactional(rollbackFor = Exception.class)
    @RequiresPermissions(value={"13"},logical = Logical.OR)
    public R updateroleprev(@RequestBody JSONObject jsonObject) throws Default200Exception {


        //删除redis键值对 todo

        List<String> newlist = (List<String>) jsonObject.get("nowlist");
        Integer roleid = jsonObject.getInteger("roleid");


        //检查是否可以修改角色的权限


        //先把当前角色所有权限删除
        int a = sysRoleprivilegeService.deleteByRoleid(roleid);
        log.info("删除了{}条关于角色id为{}的权限", a, roleid);

        //需要保存的二级菜单权限
        List<String> prevs2 = newlist.stream().filter(e -> (!e.startsWith("A")) && (!e.startsWith("B"))).collect(Collectors.toList());
        //直接加
        ArrayList<SysRoleprivilegeEntity> roleprevs2 = new ArrayList<>();
        for (String s2 : prevs2) {
            roleprevs2.add(new SysRoleprivilegeEntity(roleid, Integer.parseInt(s2)));
        }
        //保存二级菜单权限
        boolean b = sysRoleprivilegeService.saveBatch(roleprevs2);
        log.info("添加{}了{}条关于角色id为{}的二级菜单权限", b, roleprevs2.size(), roleid);


        //根据二级权限点反查1级权限点
        List<SysMenuprivilegeEntity> sysMenuprivilegeEntities = sysMenuprivilegeService.getARankByPids(prevs2);


        ArrayList<SysRoleprivilegeEntity> roleprevs = new ArrayList<>();
        for (SysMenuprivilegeEntity s : sysMenuprivilegeEntities) {
            Integer privilegeid = s.getPrivilegeid();
            //加入到role-prev表中
            roleprevs.add(new SysRoleprivilegeEntity(roleid, privilegeid));
        }
        //保存一级菜单
        boolean b1 = sysRoleprivilegeService.saveBatch(roleprevs);
        log.info("添加{}了{}条关于角色id为{}的一级菜单权限", b1, roleprevs.size(), roleid);

        if (!(b || b1)) {
            throw new Default200Exception(ErrorConstant.error_update_failed);
        }
        return R.ok();

    }


}
